package org.tony.nio.demo;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLConnection;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

/**
 * 一个简单的MappedBuffer测试 模拟一个HTTP 服务器，查找指定文件，在找到的情况下，返回查找成功 否则查找失败<br>
 * 
 * @author tangilin
 * 
 */
public class MappedBufferDemo
{

	private static final String	OUTPUT_FILE		= "MappedHttp.out";
	private static final String	LINE_SEP		= "\r\n";
	private static final String	SERVER_ID		= "Server: Ronsoft Dummy Server";
	private static final String	HTTP_HDR		= "HTTP/1.0 200 OK" + LINE_SEP + SERVER_ID + LINE_SEP;
	private static final String	HTTP_404_HDR	= "HTTP/1.0 404 Not Found" + LINE_SEP + SERVER_ID + LINE_SEP;
	private static final String	MSG_404			= "Could not open file: ";

	public static void main(String[] args) throws Exception
	{
		if (args.length < 1)
		{
			System.err.println("Usage: fileName");
			return;
		}

		String fileName = args[0];
		ByteBuffer bf = ByteBuffer.wrap(bytes(HTTP_HDR));
		ByteBuffer dynhdrs = ByteBuffer.allocate(128);
		ByteBuffer[] gather = new ByteBuffer[] { bf, dynhdrs, null };
		String contentType = "unkown/unkonw";
		long contentLength = -1;
		try
		{
			FileInputStream fis = new FileInputStream(fileName);
			FileChannel fc = fis.getChannel();

			MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
			gather[2] = mbb;
			contentLength = fc.size();
			contentType = URLConnection.guessContentTypeFromName(fileName);
		}
		catch (Exception e)
		{
			ByteBuffer buffer = ByteBuffer.allocate(128);
			String msg = MSG_404 + e + LINE_SEP;
			buffer.put(bytes(msg));
			buffer.flip();
			gather[0] = ByteBuffer.wrap(bytes(HTTP_404_HDR));
			gather[2] = buffer;
			contentLength = msg.length();
			contentType = "text/plain";
		}

		StringBuffer sb = new StringBuffer();
		sb.append("Content-Length: " + contentLength);
		sb.append(LINE_SEP);
		sb.append("Content-Type: ").append(contentType);
		sb.append(LINE_SEP).append(LINE_SEP);
		dynhdrs.put(bytes(sb.toString()));
		dynhdrs.flip();
		FileOutputStream fos = new FileOutputStream(OUTPUT_FILE);
		FileChannel out = fos.getChannel();
		while (out.write(gather) > 0)
		{ // Empty body; loop until all buffers are empty
		}
		out.close();
		System.out.println("output written to " + OUTPUT_FILE);
	}

	private static byte[] bytes(String src) throws UnsupportedEncodingException
	{
		return src.getBytes("UTF-8");
	}

}
